home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-25 | 10.3 KB | 369 lines | [TEXT/MPS ] |
- {$P}
- {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
- { UBusyCursor.inc1.p }
- { Copyright © 1985-1990 Apple Computer, Inc. All rights reserved. }
-
- {$IFC NOT qDebugTheDebugger}
- {$W+}
- {$R-}
- {$Init-}
- {$OV-}
- {$ENDC}
-
- TYPE
- QElemWithA5 = RECORD
- OldA5: Longint; { A place to store the old value of A5 since
- when debugging the compiler trashes the
- value of A0 for any locals in the VBL task
- thus makeing the pointer to the
- paramblockrec unavailable }
- A5: Longint; { The value of A5 will be stored here to be
- available at VBL time }
- q: QElem; { vbl queue element for changing the cursor}
- END;
-
- CursorInfoPtr = ^CursorInfo;
- CursorInfo = RECORD
- aQElemWithA5: QElemWithA5; { vbl queue elem. for changing the cursor }
- inColor: BOOLEAN; { Is the saved cursor in color? }
- origCursor: Cursor; { Cursor at the time the busy cursor was put
- up, if not in color }
- origCCursor: CCrsrHandle; { Cursor at the time the busy cursor was put
- up, if in color }
- watchDelay: INTEGER; { time in 1/60 second before cursor changes
- to watch }
- inControl: BOOLEAN; { managed by MacApp; TRUE iff MacApp is in
- control; if FALSE we don't change the
- cursor at all }
- changeToWatch: BOOLEAN; { if TRUE, we automagically switch to the
- watch in the VBL task and switch to
- origCursor on a call to GetNextEvent or
- EventAvail; applications can changed this
- as necessary }
- watchOn: BOOLEAN; { TRUE if the busy cursor on }
- watchCursor: Cursor; { the watch cursor }
- END;
-
- VAR
- pBusyCursorInstalled: BOOLEAN;
- pCursorInfo: CursorInfo;
- pEAPatch: TrapPatch; { patch for EventAvail }
- pSDPatch: TrapPatch; { patch for StillDown under gravy sucking
- A/UX }
- pWMUPatch: TrapPatch; { patch for WaitMouseUp under gravy sucking
- A/UX }
- pGNEPatch: TrapPatch; { patch for GetNextEvent }
- pICPatch: TrapPatch; { patch for InitCursor }
- pSCPatch: TrapPatch; { patch for SetCursor }
- pSCCPatch: TrapPatch; { patch for SetCCursor }
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAInit}
-
- PROCEDURE InitUBusyCursor;
-
- BEGIN
- pBusyCursorInstalled := FALSE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$W+}
- {$R-}
- {$Init-}
- {$OV-}
- {$S MABusyCursorRes}
-
- PROCEDURE AWatchTask;
-
- CONST
- theOffset = sizeof(Longint) * 2;
-
- BEGIN
-
- { Set up application's A5 because the call to SetCursor assumes it & we need it to get pCursorInfo.
- Our A5 is prepended to the QElem which is pointed at by A0 }
-
- pCursorInfo.aQElemWithA5.OldA5 := SetA5(CursorInfoPtr(GetParmBlockPtr - theOffset)^.aQElemWithA5
- .A5);
-
- { always Reset the vblCount }
- WITH pCursorInfo DO
- BEGIN
- aQElemWithA5.q.vblQElem.vblCount := watchDelay;
-
- IF (GetCrsrBusy = 0) & inControl & changeToWatch & (NOT watchOn) THEN
- SetCursor(watchCursor);
-
- IF SetA5(aQElemWithA5.OldA5) = 0 THEN; { must discard the function result because
- when A5 gets reset we have no place to put
- the result }
- END;
- END;
- {$Pop}
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$S MABusyCursorRes}
-
- PROCEDURE BusyReset(delayTicks: INTEGER);
-
- BEGIN
- WITH pCursorInfo DO
- IF inControl & changeToWatch THEN
- BEGIN
- IF watchOn THEN
- IF inColor THEN
- SetCCursor(origCCursor)
- ELSE
- SetCursor(origCursor);
- aQElemWithA5.q.vblQElem.vblCount := delayTicks;
- END;
- END;
- {$Pop}
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$S MABusyCursorRes}
-
- PROCEDURE BusyActivate(entering: BOOLEAN);
-
- BEGIN
- BusyReset(pCursorInfo.watchDelay);
- pCursorInfo.inControl := entering;
-
- END;
- {$Pop}
-
- {--------------------------------------------------------------------------------------------------}
- {$S MABusyCursorRes}
-
- PROCEDURE BusyDelay(newDelay: INTEGER);
-
- BEGIN
- WITH pCursorInfo DO
- IF newDelay > 0 THEN { save new delay time }
- BEGIN
- watchDelay := newDelay;
- BusyReset(newDelay); { reset timer }
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MABusyCursorRes}
-
- PROCEDURE ForceBusy;
-
- BEGIN
- { trigger on next tick and reset timer }
- BusyReset(1);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$S MABusyCursorRes}
-
- PROCEDURE BusyTurnOff;
-
- { This is called from InitMacAppCursor, SetMacAppCursor and SetCMacAppCursor.
- It sets pCursorInfo fields to indicate that the cursor is not the
- busy watch. }
-
- BEGIN
- WITH pCursorInfo DO
- IF inControl & changeToWatch THEN
- BEGIN
- watchOn := FALSE; { anyone that sets the busy cursor should
- set this TRUE explicitly }
- aQElemWithA5.q.vblQElem.vblCount := pCursorInfo.watchDelay;
- END;
- END;
- {$Pop}
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$S MABusyCursorRes} { must be in Main segment, and cannot call
- to any other segment because SetCursor is
- called from the AWatchTask VBL task }
-
- PROCEDURE SetCMacAppCursor(theCCursor: CCrsrHandle);
-
- { The SetCCursor patch, used to remember the color cursor being set.
- Installed as a "Head" patch, meaning the original SetCCursor trap
- is called after this code has completed.}
-
- VAR
- OldA5: Longint;
-
- BEGIN
- OldA5 := SetCurrentA5; { ***** Called from trap patches *****}
- BusyTurnOff;
- WITH pCursorInfo DO
- BEGIN
- inColor := TRUE;
- { Save a copy of the color cursor }
- pCursorInfo.origCCursor := theCCursor;
- END;
-
- OldA5 := SetA5(OldA5); { srf 88.9.6 }
- END;
- {$Pop}
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$S MABusyCursorRes} { must be in Main segment, and cannot call
- to any other segment because SetCursor is
- called from the AWatchTask VBL task }
-
- PROCEDURE SetMacAppCursor(VAR theCursor: Cursor);
-
- { Patches SetCursor to remember the cursor being set. Installed as a
- "Head" patch, meaning the original SetCursor trap is called after
- this code has completed. Also called from InitMacAppCursor. }
-
- VAR
- OldA5: Longint;
-
- BEGIN
- OldA5 := SetCurrentA5; { ***** Called from trap patches *****}
- BusyTurnOff;
- { If we are setting the cursor to the busy watch, then don't save it }
- IF @theCursor <> @pCursorInfo.watchCursor THEN
- BEGIN
- pCursorInfo.inColor := FALSE;
- pCursorInfo.origCursor := theCursor;
- END
- ELSE
- pCursorInfo.watchOn := TRUE; { because BusyTurnOff set it to FALSE }
- OldA5 := SetA5(OldA5); { srf 88.9.6 }
- END;
- {$Pop}
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$S MABusyCursorRes}
-
- PROCEDURE InitMacAppCursor;
-
- { Called when the InitCursor trap is executed. After completion, we jump
- to the ROM InitCursor. }
-
- VAR
- OldA5: Longint;
-
- BEGIN
- OldA5 := SetCurrentA5; { ***** Called from trap patches *****}
- SetMacAppCursor(arrow);
- OldA5 := SetA5(OldA5); { srf 88.9.6 }
- END;
- {$Pop}
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAInit}
-
- PROCEDURE BusyInstall;
-
- BEGIN
- IF NOT pBusyCursorInstalled THEN
- BEGIN
- UseROMMap(TRUE);
-
- { Setup the pCursorInfo record }
-
- pCursorInfo.watchCursor := GetCursor(watchCursor)^^;
- WITH pCursorInfo DO
- BEGIN
- inControl := TRUE; { we are in control during initialization }
- changeToWatch := TRUE;
- watchOn := FALSE;
- watchDelay := kWatchDelay;
- inColor := FALSE;
- origCursor := arrow;
-
- { Setup the VBL task }
- WITH aQElemWithA5.q.vblQElem DO
- BEGIN
- qType := ORD(vType);
- vblAddr := @AWatchTask;
- vblCount := kWatchDelay;
- vblPhase := 0;
- END;
- aQElemWithA5.A5 := Longint(GetA5);
- { This will make the A5 world available to the VBL task }
-
- { Patch the necessary traps }
- FailOSErr(Head1Patch(pSCPatch, _SetCursor, @SetMacAppCursor)); { SetCursor }
- FailOSErr(HeadPatch(pICPatch, _InitCursor, @InitMacAppCursor)); { InitCursor }
- IF qNeedsColorQD | gConfiguration.hasColorQD THEN
- FailOSErr(Head1Patch(pSCCPatch, _SetCCursor, @SetCMacAppCursor)); { SetCCursor }
-
- { Install the VBL task }
- FailOSErr(VInstall(@aQElemWithA5.q));
- END;
-
- { Patch the traps applicable }
- FailOSErr(HeadPatch(pGNEPatch, _GetNextEvent, @ResetBusyCursor)); { GetNextEvent }
- FailOSErr(HeadPatch(pEAPatch, _EventAvail, @ResetBusyCursor)); { EventAvail }
- IF gConfiguration.hasAUX THEN
- BEGIN
- FailOSErr(HeadPatch(pSDPatch, _StillDown, @ResetBusyCursor)); { StillDown }
- FailOSErr(HeadPatch(pWMUPatch, _WaitMouseUp, @ResetBusyCursor)); { WaitMouseUp }
- END;
-
- { Turn on busy cursor right now; init watchDelay }
- BusyDelay(kWatchDelay);
- ForceBusy;
-
- pBusyCursorInstalled := TRUE;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MATerminate}
-
- PROCEDURE BusyRemove;
-
- VAR
- e: OSErr;
-
- BEGIN
- IF pBusyCursorInstalled THEN
- BEGIN
- BusyReset(1); { Restore the non-busy cursor }
- { Remove the VBL task }
- e := VRemove(@pCursorInfo.aQElemWithA5.q);
-
- { Unpatch the patches }
- UnpatchTrap(pICPatch);
- UnpatchTrap(pSCPatch);
- IF qNeedsColorQD | gConfiguration.hasColorQD THEN
- UnpatchTrap(pSCCPatch);
-
- UnpatchTrap(pGNEPatch);
- UnpatchTrap(pEAPatch);
- IF gConfiguration.hasAUX THEN
- BEGIN
- UnpatchTrap(pSDPatch);
- UnpatchTrap(pWMUPatch);
- END;
-
- pBusyCursorInstalled := FALSE;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$Push} {$IFC qTrace} {$D+} {$ENDC}
- {$S MABusyCursorRes}
-
- PROCEDURE ResetBusyCursor;
-
- VAR
- OldA5: Longint;
-
- BEGIN
- OldA5 := SetCurrentA5; { ***** Called from trap patches *****}
- BusyReset(pCursorInfo.watchDelay);
- OldA5 := SetA5(OldA5); { srf 88.9.6 }
- END;
- {$Pop}
-